package cn.com.bluemoon.daps.domp.api;

import cn.com.bluemoon.daps.common.constant.ServiceNameConstants;
import com.alibaba.fastjson.JSON;
import io.swagger.annotations.Api;
import lombok.Data;
import lombok.ToString;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.http.MediaType;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.FileCopyUtils;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestPart;
import org.springframework.web.multipart.MultipartFile;

import java.io.*;

@FeignClient(value = ServiceNameConstants.DapsApiDomp.FASTDFS_SERVICE, configuration = FeignMultipartSupportConfig.class)
@RequestMapping(value = "/fastdfs")
@Api(tags = "FeignClient服务-文件系统bd-fastdfs-service")
public interface FastDFSService {


    /**
     * 注意了这里用RequestPart，用RequestParam是会报错的，还有configuration中需要配置config的信息
     * 上传文件
     *
     * @param file
     * @return
     */
    @PostMapping(value = "/uploadFile", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
    public String uploadFile(@RequestPart("file") MultipartFile file);

    /**
     * 上传文件
     *
     * @param file
     * @return
     */
    @PostMapping(value = "/uploadImg",
            consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
    public String uploadImg(@RequestPart("file") MultipartFile file);


    /**
     * 定义default接口方法，统一响应内容
     * <pre>
     *     FastDfsMultipartFile multipartFile = new FastDfsMultipartFile("file", f.getName(),
     *     "multipart/form-data", new FileInputStream(f));
     * </pre>
     *
     * @param file {@link FastDfsMultipartFile} 进行入参构建
     * @return 统一响应内容
     */
    default UploadResult uploadFile0(MultipartFile file){
        String result = uploadFile(file);
        UploadResult uploadResult = JSON.parseObject(result, UploadResult.class);
        return uploadResult;
    }
    /**
     * 定义default接口方法，统一响应内容
     *
     * @param file {@link FastDfsMultipartFile} 进行入参构建
     * @return 统一响应内容
     */
    default UploadResult uploadImg0(MultipartFile file){
        String result = uploadImg(file);
        UploadResult uploadResult = JSON.parseObject(result, UploadResult.class);
        return uploadResult;
    }

    /**
     * 定义对外的MultipartFile
     */
    public static class FastDfsMultipartFile implements MultipartFile {
        private final String name;
        private final byte[] content;
        private String originalFilename;
        @Nullable
        private String contentType;

        public FastDfsMultipartFile(String name, @Nullable byte[] content) {
            this(name, "", (String) null, (byte[]) content);
        }

        public FastDfsMultipartFile(String name, InputStream contentStream) throws IOException {
            this(name, "", (String) null, (byte[]) FileCopyUtils.copyToByteArray(contentStream));
        }

        public FastDfsMultipartFile(String name, @Nullable String originalFilename, @Nullable String contentType, @Nullable byte[] content) {
            Assert.hasLength(name, "Name must not be null");
            this.name = name;
            this.originalFilename = originalFilename != null ? originalFilename : "";
            this.contentType = contentType;
            this.content = content != null ? content : new byte[0];
        }

        public FastDfsMultipartFile(String name, @Nullable String originalFilename, @Nullable String contentType, InputStream contentStream) throws IOException {
            this(name, originalFilename, contentType, FileCopyUtils.copyToByteArray(contentStream));
        }

        @Override
        public String getName() {
            return this.name;
        }

        @Override
        public String getOriginalFilename() {
            return this.originalFilename;
        }

        @Nullable
        @Override
        public String getContentType() {
            return this.contentType;
        }

        @Override
        public boolean isEmpty() {
            return this.content.length == 0;
        }

        @Override
        public long getSize() {
            return (long) this.content.length;
        }

        @Override
        public byte[] getBytes() throws IOException {
            return this.content;
        }

        @Override
        public InputStream getInputStream() throws IOException {
            return new ByteArrayInputStream(this.content);
        }

        @Override
        public void transferTo(File dest) throws IOException, IllegalStateException {
            FileCopyUtils.copy(this.content, dest);
        }
    }

    @Data
    @ToString
    public class UploadResult implements Serializable {
        private Integer error;
        private String message, url;
    }
}
